package city.spring.modules.personnel.service.impl;

import city.spring.modules.ext.EntityExtUtils;
import city.spring.modules.ext.entity.TrainEmployeeExt;
import city.spring.modules.ext.entity.TrainOldmanExt;
import city.spring.modules.ext.service.TrainEmployeeExtService;
import city.spring.modules.ext.service.TrainOldmanExtService;
import city.spring.modules.oldman.entity.OldmanInfoEntity;
import city.spring.modules.oldman.service.OldmanInfoService;
import city.spring.modules.personnel.entity.EmployeeEntity;
import city.spring.modules.personnel.entity.EmployeeTrainingEntity;
import city.spring.modules.personnel.repository.EmployeeTrainingRepository;
import city.spring.modules.personnel.service.EmployeeService;
import city.spring.modules.personnel.service.EmployeeTrainingService;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * Service：员工培训
 *
 * @author Panxm
 * @date 2020-04-14 16:35:31
 */
@CacheConfig(cacheNames = {EmployeeTrainingServiceImpl.CACHE_NAME})
@Transactional(rollbackFor = Throwable.class)
@Service
public class EmployeeTrainingServiceImpl extends ServiceImpl<EmployeeTrainingRepository, EmployeeTrainingEntity> implements EmployeeTrainingService {
    private final TrainEmployeeExtService trainEmployeeExtService;
    private final EmployeeService employeeService;
    private final OldmanInfoService oldmanInfoService;
    private final TrainOldmanExtService trainOldmanExtService;

    public EmployeeTrainingServiceImpl(TrainEmployeeExtService trainEmployeeExtService, EmployeeService employeeService, OldmanInfoService oldmanInfoService, TrainOldmanExtService trainOldmanExtService) {
        this.trainEmployeeExtService = trainEmployeeExtService;
        this.employeeService = employeeService;
        this.oldmanInfoService = oldmanInfoService;
        this.trainOldmanExtService = trainOldmanExtService;
    }

    @Override
    public void loadEmployees(EmployeeTrainingEntity entity) {
        // 人员类型为员工时，从培训-员工联系表获取员工id，通过员工id查员工信息。老人同理。
        if (Objects.equals(entity.getPersonType(), "员工")) {
            LambdaQueryChainWrapper<TrainEmployeeExt> wrapper = trainEmployeeExtService.lambdaQuery()
                    .eq(TrainEmployeeExt::getTrainId, entity.getId());
            // 获取当前对象关联的员工ID列表信息
            List<String> employeeIds = wrapper.list()
                    .stream()
                    .map(TrainEmployeeExt::getRelatedId)
                    .collect(Collectors.toList());
            // 从数据库中查出这些员工ID的员工信息
            List<EmployeeEntity> employeeEntities = employeeService.lambdaQuery()
                    .in(EmployeeEntity::getId, employeeIds)
                    .list();
            entity.setEmployees(employeeEntities);
        }
        if (Objects.equals(entity.getPersonType(), "老人")) {
            LambdaQueryChainWrapper<TrainOldmanExt> wrapper = trainOldmanExtService.lambdaQuery()
                    .eq(TrainOldmanExt::getTrainId, entity.getId());
            // 获取当前对象关联的老人ID列表信息
            List<String> oldmanIds = wrapper.list()
                    .stream()
                    .map(TrainOldmanExt::getOldmanId)
                    .collect(Collectors.toList());
            // 从数据库中查出这些老人ID的信息
            List<OldmanInfoEntity> oldmanEntities = oldmanInfoService.lambdaQuery()
                    .in(OldmanInfoEntity::getId, oldmanIds)
                    .list();
            entity.setOldmans(oldmanEntities);
        }
    }

    @Override
    public void saveEmployeeTraining(EmployeeTrainingEntity entity) {
        EmployeeTrainingEntity findEntity = lambdaQuery().eq(EmployeeTrainingEntity::getName, entity.getName()).one();
        if (findEntity != null) {
            throw new RuntimeException("已经存在该标题");
        }
        save(entity);
        // 人员类型为员工，则设置培训-员工的联系。类型为老人，同理。
        if (Objects.equals(entity.getPersonType(), "员工")) {
            // 培训-员工关联关系
            setTrainperson(entity);
        } else {
            // 培训-老人关联关系
            setTrainoldman(entity);
        }

    }

    @Override
    public void setTrainperson(EmployeeTrainingEntity entity) {
        // 删除旧的 培训-培训人员 关联关系  后 再  添加新的关联关系
        EntityExtUtils.repairRelation(trainEmployeeExtService, entity,
                EmployeeTrainingEntity::getId, EmployeeTrainingEntity::getEmployees, EmployeeEntity::getId,
                TrainEmployeeExt::new, TrainEmployeeExt::getTrainId);
    }

    @Override
    public void setTrainoldman(EmployeeTrainingEntity entity) {
        // 删除旧的 培训-老人关联关系  后 再  添加新的关联关系
        EntityExtUtils.repairRelation(trainOldmanExtService, entity,
                EmployeeTrainingEntity::getId, EmployeeTrainingEntity::getOldmans, OldmanInfoEntity::getId,
                TrainOldmanExt::new, TrainOldmanExt::getTrainId);
    }

    @Override
    public void updateEmployeeTraining(EmployeeTrainingEntity entity) {
        // 使用 updateById(entity); 修改数据时，将会修改 entity 对象中所有非null数据，如果某个字段为null，将会忽略该字段的修改
        boolean update = updateById(entity);
        if (!update) {
            throw new RuntimeException("修改信息失败");
        }
    }

    @Override
    public void deleteEmployeeTraining(String primaryKey) {
        removeById(primaryKey);
    }

    @Override
    public void deleteEmployeeTraining(List<String> primaryKeys) {
        removeByIds(primaryKeys);
    }
}